/**
 * 
 */
package org.vsg.stock.core.indicator.coordinate;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import org.vsg.stock.core.kline.DailyKLineStock;

/**
 * @author Bill Vison
 *
 */
public abstract class AbstractCoordinate<T extends DailyKLineStock> implements Coordinate {

	private List<Date> xAxisIndexes = new Vector<Date>();
	
	private DecimalFormat decFormat = new DecimalFormat("######0.00000");	
	
	protected double getXValueFromODP(Date orginalXValue) {
		
		double absoluteValue = xAxisIndexes.indexOf( orginalXValue );
		
		// --- get difference from absolute value ---
		double difference = absoluteValue - getOriginXValueRelative();
		
		double xValue = difference / context.getUnitDefinition().getXUnit();
		
		return xValue;
	}
	
	
	protected double getYValueFromODP(double orginalYValue) {
		
		double difference = orginalYValue - getOriginYValueRelative();

		double yValue = difference / context.getUnitDefinition().getYUnit();
		
		
		return Double.parseDouble( decFormat.format(yValue) );
	}

	private OPConverter converter;

	@Override
	public void setOPConverter(OPConverter converter) {
		// TODO Auto-generated method stub
		this.converter = converter;
	}
	
	protected OPConverter getConverter() {
		return this.converter;
	}

	private CoordinateContext context;
	
	private CoordinateConfiguration configuration;
	
	private String stockCode;	

	
	public String getStockCode() {
		return stockCode;
	}

	public void setStockCode(String stockCode) {
		this.stockCode = stockCode;
	}


	public CoordinateContext getContext() {
		return context;
	}

	public void setContext(CoordinateContext context) {
		this.context = context;
	}

	private List<DailyKLineStock> klineListInThisCycle;
	

	public List<DailyKLineStock> getKlineListInThisCycle() {
		return klineListInThisCycle;
	}

	public void setKlineListInThisCycle(List<DailyKLineStock> klineListInThisCycle) {
		this.klineListInThisCycle = klineListInThisCycle;
	}
	
	
	@Override
	public void init()	{
		configuration.init();
		
		CoordinateContextImpl coorContext = new CoordinateContextImpl();

		OriginalDataPoint originPoint = configuration.getOriginPoint();
		UnitDefinition unitDef = configuration.getUnitDefinition();		
		
		coorContext.setOriginPoint( originPoint );
		coorContext.setUnitDefinition( unitDef );
		coorContext.setStockCode( stockCode );

		this.context = coorContext;
		
		// --- build xAxis indexes ---
		for (DailyKLineStock dks : klineListInThisCycle) {
			this.xAxisIndexes.add(dks.getDate());
		}
		
		OriginalDataPoint odp = coorContext.getOriginPoint();
		
		originXValueRelative = xAxisIndexes.indexOf( odp.getXvalue() );

		originYValueRelative = odp.getYvalue();
	}
	
	private double originXValueRelative;
	
	private double originYValueRelative;
	
	protected double getOriginXValueRelative() {
		return originXValueRelative;
	}

	protected double getOriginYValueRelative() {
		return originYValueRelative;
	}


	protected Date getXDateFromIndex(double index) {
		return this.xAxisIndexes.get((int)index);
	}


	/**
	 * @param configuration
	 */
	public void setConfiguration( CoordinateConfiguration configuration ) {
		this.configuration = configuration;
	}
	
	@Override
	public CoordinatePoint getOrigin() {
		SimpleCoordinatePoint scp = new SimpleCoordinatePoint();
		scp.setXvalue(0);
		scp.setYvalue(0);
		return scp;
	}
	
	
}
